{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Methods and Exceptions\n",
        "\n",
        "Watch the full [C# 101 video](https://www.youtube.com/watch?v=8YsoBBiVVzQ&list=PLdo4fOcmZ0oVxKLQCHpiUWun7vlJJvUiN&index=18) for this module.\n",
        "\n",
        "Below is the code you've made so far. Balance is gotten by summing up the lists of transactions, but you haven't written a way to add a transaction. This happens plenty of times in coding, where to make something more robust, you have to take a step back before going forward.\n",
        "\n",
        "> Run the code cells below."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "dotnet_interactive": {
          "language": "csharp"
        },
        "vscode": {
          "languageId": "csharp"
        }
      },
      "outputs": [],
      "source": [
        "public class Transaction\n",
        "{\n",
        "    // Properties\n",
        "    public decimal Amount { get; }\n",
        "    public DateTime Date { get; }\n",
        "    public string Notes\n",
        "    {\n",
        "        get;\n",
        "\n",
        "    }\n",
        "\n",
        "    // Constructor\n",
        "    public Transaction(decimal amount, DateTime date, string note)\n",
        "    {\n",
        "        this.Amount = amount;\n",
        "        this.Date = date;\n",
        "        this.Notes = note;\n",
        "    }\n",
        "}"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "dotnet_interactive": {
          "language": "csharp"
        },
        "vscode": {
          "languageId": "csharp"
        }
      },
      "outputs": [],
      "source": [
        "using System.Collections.Generic;\n",
        "\n",
        "public class BankAccount\n",
        "{\n",
        "    // Properties\n",
        "    public string Number { get; }\n",
        "    public string Owner { get; set; }\n",
        "    public decimal Balance\n",
        "    {\n",
        "        get\n",
        "\n",
        "        {\n",
        "            decimal balance = 0;\n",
        "            foreach (var item in allTransactions)\n",
        "            {\n",
        "                balance += item.Amount;\n",
        "            }\n",
        "\n",
        "            return balance;\n",
        "        }\n",
        "\n",
        "    }\n",
        "    private static int accountNumberSeed = 1234567890;\n",
        "    private List<Transaction> allTransactions = new List<Transaction>();\n",
        "\n",
        "    // Constructor\n",
        "    public BankAccount(string name, decimal initialBalance)\n",
        "    {\n",
        "        this.Owner = name;\n",
        "        this.Number = accountNumberSeed.ToString();\n",
        "        accountNumberSeed++;\n",
        "\n",
        "    }\n",
        "\n",
        "    // Functions\n",
        "    public void MakeDeposit(decimal amount, DateTime date, string note)\n",
        "    {\n",
        "    }\n",
        "\n",
        "    public void MakeWithdrawal(decimal amount, DateTime date, string note)\n",
        "    {\n",
        "    }\n",
        "}"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "dotnet_interactive": {
          "language": "csharp"
        },
        "vscode": {
          "languageId": "csharp"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Account 1234567890 was created for Kendra with 0 dollars\r\n"
          ]
        }
      ],
      "source": [
        "// Testing Code\n",
        "\n",
        "var account = new BankAccount(\"Kendra\", 1000);\n",
        "Console.WriteLine($\"Account {account.Number} was created for {account.Owner} with {account.Balance} dollars\");"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## #1: Adding deposits\n",
        "\n",
        "First things first, time to make a deposit function. This addition will make a transaction listing the amount, date, and a note that you're depositing, and then adds it to the transaction list.\n",
        "\n",
        "> Add this code inside MakeDeposit.\n",
        "\n",
        "```csharp\n",
        "    var deposit = new Transaction(amount, date, note);\n",
        "    allTransactions.Add(deposit);\n",
        "```"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "dotnet_interactive": {
          "language": "csharp"
        },
        "vscode": {
          "languageId": "csharp"
        }
      },
      "outputs": [],
      "source": [
        "using System.Collections.Generic;\n",
        "\n",
        "public class BankAccount\n",
        "{\n",
        "    // Properties\n",
        "    public string Number { get; }\n",
        "    public string Owner { get; set; }\n",
        "    public decimal Balance\n",
        "    {\n",
        "        get\n",
        "\n",
        "        {\n",
        "            decimal balance = 0;\n",
        "            foreach (var item in allTransactions)\n",
        "            {\n",
        "                balance += item.Amount;\n",
        "            }\n",
        "\n",
        "            return balance;\n",
        "        }\n",
        "\n",
        "\n",
        "    }\n",
        "    private static int accountNumberSeed = 1234567890;\n",
        "    private List<Transaction> allTransactions = new List<Transaction>();\n",
        "\n",
        "    // Constructor\n",
        "    public BankAccount(string name, decimal initialBalance)\n",
        "    {\n",
        "        this.Owner = name;\n",
        "        this.Number = accountNumberSeed.ToString();\n",
        "        accountNumberSeed++;\n",
        "\n",
        "    }\n",
        "\n",
        "    // Functions\n",
        "    public void MakeDeposit(decimal amount, DateTime date, string note)\n",
        "    {\n",
        "        //Add code here!\n",
        "    }\n",
        "\n",
        "    public void MakeWithdrawal(decimal amount, DateTime date, string note)\n",
        "    {\n",
        "    }\n",
        "}"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## #2: Exceptions\n",
        "\n",
        "But what if someone tries to deposit negative money? That doesn't make logical sense, but currently the method allows for that. What you can do is make an exception. Before doing anything, you check that the amount deposited is more than 0. If it is, awesome, the code moves on to adding the transaction. If not, the code throws an exception, where it stops the code and prints out the issue.\n",
        "\n",
        "> Place this code in the very beginning of the `MakeDeposit` method.\n",
        "\n",
        "```\n",
        "if (amount <= 0)\n",
        "    {\n",
        "        throw new ArgumentOutOfRangeException(nameof(amount), \"Amount of deposit must be positive\");\n",
        "    }\n",
        "```"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "dotnet_interactive": {
          "language": "csharp"
        },
        "vscode": {
          "languageId": "csharp"
        }
      },
      "outputs": [],
      "source": [
        "using System.Collections.Generic;\n",
        "\n",
        "public class BankAccount\n",
        "{\n",
        "    // Properties\n",
        "    public string Number { get; }\n",
        "    public string Owner { get; set; }\n",
        "    public decimal Balance\n",
        "    {\n",
        "        get\n",
        "\n",
        "        {\n",
        "            decimal balance = 0;\n",
        "            foreach (var item in allTransactions)\n",
        "            {\n",
        "                balance += item.Amount;\n",
        "            }\n",
        "\n",
        "            return balance;\n",
        "        }\n",
        "\n",
        "    }\n",
        "    private static int accountNumberSeed = 1234567890;\n",
        "    private List<Transaction> allTransactions = new List<Transaction>();\n",
        "\n",
        "    // Constructor\n",
        "    public BankAccount(string name, decimal initialBalance)\n",
        "    {\n",
        "        this.Owner = name;\n",
        "        this.Number = accountNumberSeed.ToString();\n",
        "        accountNumberSeed++;\n",
        "\n",
        "    }\n",
        "\n",
        "    // Functions\n",
        "    public void MakeDeposit(decimal amount, DateTime date, string note)\n",
        "    {\n",
        "        //Add Code here!\n",
        "\n",
        "        var deposit = new Transaction(amount, date, note);\n",
        "        allTransactions.Add(deposit);\n",
        "    }\n",
        "\n",
        "    public void MakeWithdrawal(decimal amount, DateTime date, string note)\n",
        "    {\n",
        "    }\n",
        "}"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## #3: Adding withdrawal\n",
        "\n",
        "Now you need to do the same thing for the withdrawal!\n",
        "\n",
        "> Add this code to MakeWithdrawal.\n",
        "\n",
        "```csharp\n",
        "if (amount <= 0)\n",
        "    {\n",
        "        throw new ArgumentOutOfRangeException(nameof(amount), \"Amount of withdrawal must be positive\");\n",
        "    }\n",
        "    if (Balance - amount < 0)\n",
        "    {\n",
        "        throw new InvalidOperationException(\"Not sufficient funds for this withdrawal\");\n",
        "    }\n",
        "    var withdrawal = new Transaction(-amount, date, note);\n",
        "    allTransactions.Add(withdrawal);\n",
        "```"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "dotnet_interactive": {
          "language": "csharp"
        },
        "vscode": {
          "languageId": "csharp"
        }
      },
      "outputs": [],
      "source": [
        "using System.Collections.Generic;\n",
        "\n",
        "public class BankAccount\n",
        "{\n",
        "    // Properties\n",
        "    public string Number { get; }\n",
        "    public string Owner { get; set; }\n",
        "    public decimal Balance\n",
        "    {\n",
        "        get\n",
        "\n",
        "        {\n",
        "            decimal balance = 0;\n",
        "            foreach (var item in allTransactions)\n",
        "            {\n",
        "                balance += item.Amount;\n",
        "            }\n",
        "\n",
        "            return balance;\n",
        "        }\n",
        "\n",
        "\n",
        "    }\n",
        "    private static int accountNumberSeed = 1234567890;\n",
        "    private List<Transaction> allTransactions = new List<Transaction>();\n",
        "\n",
        "    // Constructor\n",
        "    public BankAccount(string name, decimal initialBalance)\n",
        "    {\n",
        "        this.Owner = name;\n",
        "        this.Number = accountNumberSeed.ToString();\n",
        "        accountNumberSeed++;\n",
        "\n",
        "    }\n",
        "\n",
        "    // Functions\n",
        "    public void MakeDeposit(decimal amount, DateTime date, string note)\n",
        "    {\n",
        "        if (amount <= 0)\n",
        "        {\n",
        "            throw new ArgumentOutOfRangeException(nameof(amount), \"Amount of deposit must be positive\");\n",
        "        }\n",
        "        var deposit = new Transaction(amount, date, note);\n",
        "        allTransactions.Add(deposit);\n",
        "    }\n",
        "\n",
        "    public void MakeWithdrawal(decimal amount, DateTime date, string note)\n",
        "    {\n",
        "        //Add code here!\n",
        "    }\n",
        "}"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## #4: Creating initial deposit\n",
        "\n",
        "Now that you have deposits and withdrawals, you can finally make an initial deposit again. What you'll do is create a deposit of the initial amount when you're first constructing the bank account.\n",
        "\n",
        "> Add this code to the `BankAccount` constructor.\n",
        "\n",
        "```\n",
        "MakeDeposit(initialBalance, DateTime.Now, \"Initial balance\");\n",
        "```"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "dotnet_interactive": {
          "language": "csharp"
        },
        "vscode": {
          "languageId": "csharp"
        }
      },
      "outputs": [],
      "source": [
        "using System.Collections.Generic;\n",
        "\n",
        "public class BankAccount\n",
        "{\n",
        "    // Properties\n",
        "    public string Number { get; }\n",
        "    public string Owner { get; set; }\n",
        "    public decimal Balance\n",
        "    {\n",
        "        get\n",
        "\n",
        "        {\n",
        "            decimal balance = 0;\n",
        "            foreach (var item in allTransactions)\n",
        "            {\n",
        "                balance += item.Amount;\n",
        "            }\n",
        "\n",
        "            return balance;\n",
        "        }\n",
        "\n",
        "\n",
        "    }\n",
        "    private static int accountNumberSeed = 1234567890;\n",
        "    private List<Transaction> allTransactions = new List<Transaction>();\n",
        "\n",
        "    // Constructor\n",
        "    public BankAccount(string name, decimal initialBalance)\n",
        "    {\n",
        "        this.Owner = name;\n",
        "        this.Number = accountNumberSeed.ToString();\n",
        "        accountNumberSeed++;\n",
        "        //(Paste here!)\n",
        "\n",
        "    }\n",
        "\n",
        "    // Functions\n",
        "    public void MakeDeposit(decimal amount, DateTime date, string note)\n",
        "    {\n",
        "        if (amount <= 0)\n",
        "        {\n",
        "            throw new ArgumentOutOfRangeException(nameof(amount), \"Amount of deposit must be positive\");\n",
        "        }\n",
        "        var deposit = new Transaction(amount, date, note);\n",
        "        allTransactions.Add(deposit);\n",
        "    }\n",
        "\n",
        "    public void MakeWithdrawal(decimal amount, DateTime date, string note)\n",
        "    {\n",
        "        if (amount <= 0)\n",
        "        {\n",
        "            throw new ArgumentOutOfRangeException(nameof(amount), \"Amount of withdrawal must be positive\");\n",
        "        }\n",
        "        if (Balance - amount < 0)\n",
        "        {\n",
        "            throw new InvalidOperationException(\"Not sufficient funds for this withdrawal\");\n",
        "        }\n",
        "        var withdrawal = new Transaction(-amount, date, note);\n",
        "        allTransactions.Add(withdrawal);\n",
        "        }\n",
        "}"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Check and test your work\n",
        "\n",
        "There's some added line in the test code, because you can now make deposits and withdrawals. Test it out!\n",
        "\n",
        "> Run the following cells, including the new stuff in the test code.\n",
        ">\n",
        "> Make your own deposit and withdrawal."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "dotnet_interactive": {
          "language": "csharp"
        },
        "vscode": {
          "languageId": "csharp"
        }
      },
      "outputs": [],
      "source": [
        "public class Transaction\n",
        "{\n",
        "    // Properties\n",
        "    public decimal Amount { get; }\n",
        "    public DateTime Date { get; }\n",
        "    public string Notes { get; }\n",
        "\n",
        "    // Constructor\n",
        "    public Transaction(decimal amount, DateTime date, string note)\n",
        "    {\n",
        "        this.Amount = amount;\n",
        "        this.Date = date;\n",
        "        this.Notes = note;\n",
        "    }\n",
        "}"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "dotnet_interactive": {
          "language": "csharp"
        },
        "vscode": {
          "languageId": "csharp"
        }
      },
      "outputs": [],
      "source": [
        "using System.Collections.Generic;\n",
        "\n",
        "public class BankAccount\n",
        "{\n",
        "    // Properties\n",
        "    public string Number { get; }\n",
        "    public string Owner { get; set; }\n",
        "    public decimal Balance\n",
        "    {\n",
        "        get\n",
        "\n",
        "        {\n",
        "            decimal balance = 0;\n",
        "            foreach (var item in allTransactions)\n",
        "            {\n",
        "                balance += item.Amount;\n",
        "            }\n",
        "\n",
        "            return balance;\n",
        "        }\n",
        "\n",
        "\n",
        "    }\n",
        "    private static int accountNumberSeed = 1234567890;\n",
        "    private List<Transaction> allTransactions = new List<Transaction>();\n",
        "\n",
        "    // Constructor\n",
        "    public BankAccount(string name, decimal initialBalance)\n",
        "    {\n",
        "\n",
        "        this.Owner = name;\n",
        "        this.Number = accountNumberSeed.ToString();\n",
        "        accountNumberSeed++;\n",
        "        MakeDeposit(initialBalance, DateTime.Now, \"Initial balance\"); //(#4)\n",
        "\n",
        "    }\n",
        "\n",
        "    // Functions\n",
        "    public void MakeDeposit(decimal amount, DateTime date, string note)\n",
        "    {\n",
        "        //(#2)\n",
        "        if (amount <= 0)\n",
        "        {\n",
        "            throw new ArgumentOutOfRangeException(nameof(amount), \"Amount of deposit must be positive\");\n",
        "        }\n",
        "        //(#1)\n",
        "        var deposit = new Transaction(amount, date, note);\n",
        "        allTransactions.Add(deposit);\n",
        "    }\n",
        "\n",
        "    public void MakeWithdrawal(decimal amount, DateTime date, string note)\n",
        "    {\n",
        "        //(#3)\n",
        "        if (amount <= 0)\n",
        "        {\n",
        "            throw new ArgumentOutOfRangeException(nameof(amount), \"Amount of withdrawal must be positive\");\n",
        "        }\n",
        "        if (Balance - amount < 0)\n",
        "        {\n",
        "            throw new InvalidOperationException(\"Not sufficient funds for this withdrawal\");\n",
        "        }\n",
        "        var withdrawal = new Transaction(-amount, date, note);\n",
        "        allTransactions.Add(withdrawal);\n",
        "    }\n",
        "}"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "dotnet_interactive": {
          "language": "csharp"
        },
        "vscode": {
          "languageId": "csharp"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Account 1234567890 was created for Kendra with 1000 dollars\r\n",
            "500\r\n",
            "600\r\n"
          ]
        }
      ],
      "source": [
        "var account = new BankAccount(\"Kendra\", 1000);\n",
        "Console.WriteLine($\"Account {account.Number} was created for {account.Owner} with {account.Balance} dollars\");\n",
        "\n",
        "account.MakeWithdrawal(500, DateTime.Now, \"Rent payment\");  //Added test code\n",
        "Console.WriteLine(account.Balance);\n",
        "account.MakeDeposit(100, DateTime.Now, \"Friend paid me back\");\n",
        "Console.WriteLine(account.Balance);"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Review\n",
        "\n",
        "You did it! You've now successfully made a bank account class that has the following attributes:\n",
        "\n",
        "> It has a 10-digit number that uniquely identifies the bank account.\n",
        ">\n",
        "> It has a string that stores the name or names of the owners.\n",
        ">\n",
        "> The balance can be retrieved.\n",
        ">\n",
        "> It accepts deposits.\n",
        ">\n",
        "> It accepts withdrawals.\n",
        ">\n",
        "> The initial balance must be positive.\n",
        ">\n",
        "> Withdrawals cannot result in a negative balance.\n",
        ">\n",
        "\n",
        "## Extra credit\n",
        "\n",
        "Now that you've created a bank account class, you can play around with it! Here's a challenge:\n",
        "> Create a way to list out the list of transactions, including the time and notes."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Continue learning\n",
        "\n",
        "You've completed this lesson, congratulations! There are plenty more places to continue learning:\n",
        "There are plenty more resources out there to learn!\n",
        "> [⏪ Last Module - Methods and Members](https://ntbk.io/csharp101-notebook14)\n",
        ">\n",
        "> [Watch the video](https://www.youtube.com/watch?v=8YsoBBiVVzQ&list=PLdo4fOcmZ0oVxKLQCHpiUWun7vlJJvUiN&index=18)\n",
        ">\n",
        "> [Documentation: Object Oriented Coding in C#](https://docs.microsoft.com/dotnet/csharp/fundamentals/tutorials/classes?WT.mc_id=Educationalcsharp-c9-scottha)\n",
        ">\n",
        "> [Start at the beginning: What is C#?](https://www.youtube.com/watch?v=BM4CHBmAPh4&list=PLdo4fOcmZ0oVxKLQCHpiUWun7vlJJvUiN&index=1)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Other resources\n",
        "\n",
        "Here's some more places to continue learning:\n",
        "\n",
        "> [Other 101 Videos](https://dotnet.microsoft.com/learn/videos?WT.mc_id=csharpnotebook-35129-website)\n",
        ">\n",
        "> [Microsoft Learn](https://docs.microsoft.com/learn/dotnet/?WT.mc_id=csharpnotebook-35129-website)\n",
        ">\n",
        "> [C# Documentation](https://docs.microsoft.com/dotnet/csharp/?WT.mc_id=csharpnotebook-35129-website)"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": ".NET (C#)",
      "language": "C#",
      "name": ".net-csharp"
    },
    "language_info": {
      "file_extension": ".cs",
      "mimetype": "text/x-csharp",
      "name": "C#",
      "pygments_lexer": "csharp",
      "version": "8.0"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 4
}
